"""测试配置文件"""
import os
import sys
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool

# 添加项目根目录到Python路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from main import app
from database import Base, get_db
from auth import AuthHandler
from models.user import User


# 使用SQLite内存数据库进行测试
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"

# 创建测试数据库引擎
engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={"check_same_thread": False},
    poolclass=StaticPool,
)

# 创建测试数据库会话
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


@pytest.fixture(scope="session")
def test_db():
    """创建测试数据库和表"""
    Base.metadata.create_all(bind=engine)
    yield
    Base.metadata.drop_all(bind=engine)


@pytest.fixture(autouse=True)
def clean_database(db):
    """在每个测试前后清理数据库"""
    # 在测试前清理数据库
    for table in reversed(Base.metadata.sorted_tables):
        db.execute(table.delete())
    db.commit()
    
    yield
    
    # 在测试后清理数据库
    for table in reversed(Base.metadata.sorted_tables):
        db.execute(table.delete())
    db.commit()


@pytest.fixture
def db(test_db):
    """创建数据库会话"""
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()


@pytest.fixture
def client(db):
    """创建测试客户端，覆盖默认的数据库依赖"""
    # 依赖注入函数
    def override_get_db():
        try:
            yield db
        finally:
            db.close()
    
    # 覆盖数据库依赖
    app.dependency_overrides[get_db] = override_get_db
    
    # 创建测试客户端
    with TestClient(app) as client:
        yield client


@pytest.fixture
def test_user(db):
    """创建测试用户"""
    # 创建用户
    user = User(
        username="testuser",
        email="test@example.com",
        password_hash=AuthHandler.get_password_hash("testpassword123"),
        status="active",
    )
    
    db.add(user)
    db.commit()
    db.refresh(user)
    
    return user


@pytest.fixture
def test_admin(db):
    """创建测试管理员用户"""
    # 创建管理员用户
    admin = User(
        username="admin",
        email="admin@example.com",
        password_hash=AuthHandler.get_password_hash("adminpassword123"),
        status="active",
        role="admin",
    )
    
    db.add(admin)
    db.commit()
    db.refresh(admin)
    
    return admin


@pytest.fixture
def auth_token(test_user):
    """创建测试用户的认证令牌"""
    return AuthHandler.create_access_token(data={"sub": str(test_user.id)})


@pytest.fixture
def admin_auth_token(test_admin):
    """创建管理员的认证令牌"""
    return AuthHandler.create_access_token(data={"sub": str(test_admin.id)})


@pytest.fixture
def auth_headers(auth_token):
    """创建认证头"""
    return {
        "Authorization": f"Bearer {auth_token}"
    }


@pytest.fixture
def admin_auth_headers(admin_auth_token):
    """创建管理员认证头"""
    return {
        "Authorization": f"Bearer {admin_auth_token}"
    }


@pytest.fixture(autouse=True)
def isolate_tests():
    """隔离测试，每个测试后清理依赖覆盖"""
    yield
    app.dependency_overrides.clear()